#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <psp2/io/dirent.h>
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include <psp2/kernel/processmgr.h>

#include <vita2d.h>

#include "states.h"
#include "init.h"
#include "ui.h"
#include "utils.h"
#include "menu.h"
#include "audio.h"
#include "video.h"
#include "browser.h"
#include "config.h"
#include "retro.h"
#include "lang.h"

#define STATES_VERSION 1

#define STATES_PADDING_L 0.0f
#define STATES_PADDING_T 8.0f

#define STATES_ENTRY_PADDING 8.0f
#define STATES_ENTRY_LINE_SPACE 8.0f

#define STATES_INFO_MARGIN_L 6.0f
#define STATES_INFO_LINE_SPACE 4.0f
#define STATES_OPATION_LINE_SPACE 4.0f

#define STATES_ENTRY_BG_COLOR COLOR_ALPHA(DARKGRAY, 0xAF)
#define STATES_ENTRY_FOCUS_BG_COLOR COLOR_ALPHA(AZURE, 0xAF)
#define STATES_PREVIEW_BG_COLOR COLOR_ALPHA(GRAY, 0xAF)

#define STATES_ENTRIES_LINE_COUNT 2
#define STATES_ENTRIES_LINES 4
#define N_STATES_ENTRIES  16

typedef struct
{
    uint32_t version;           // 0x00
    uint64_t screenshot_offset; // 0x04
    uint32_t screenshot_width;  // 0x0C
    uint32_t screenshot_height; // 0x10
    uint64_t screenshot_size;   // 0x14
    uint64_t preview_offset;    // 0x1C
    uint32_t preview_width;     // 0x24
    uint32_t preview_height;    // 0x28
    uint64_t preview_size;      // 0x2C
    uint64_t state_offset;      // 0x34
    uint64_t state_size;        // 0x3C
    char reserved[0x24];        // 0x44
} GameStateHeader;              // 0x68

typedef struct
{
    int exist;
    vita2d_texture *tex;
    SceOff size;
    SceDateTime time;
} GameStateEntry;

typedef struct
{
    char *name;
    int enable;
} StateOptionEntry;

static StateOptionEntry option_entries[] = {
    {STR_LOAD, 1},
    {STR_SAVE, 1},
    {STR_DELETE, 1},
    {STR_CANCEL, 1},
};

#define N_OPTION_ENTRIES (sizeof(option_entries) / sizeof(StateOptionEntry))

static int states_top_pos = 0, states_focus_pos = 0;
static int options_open = 0;
static int options_focus_pos = 0;

static char states_dir_path[MAX_PATH_LENGTH];

GameStateEntry *states_entries = NULL;

static SceUID init_states_thread = -1;
static int stop_states_thread = 0;

static float states_entry_view_width, states_entry_view_height, states_entry_view_x_space, states_entry_view_y_space;
static float states_entry_view_sx, states_entry_view_sy;
static float states_entry_width, states_entry_height;
static float states_entry_sx, states_entry_sy, states_entry_dx, states_entry_dy;
static float states_preview_width, states_preview_height;

void initStatesDrawInfo()
{
    states_entry_view_width = (MENU_FREE_DRAW_WIDTH - STATES_ENTRY_LINE_SPACE - STATES_PADDING_L * 2) / STATES_ENTRIES_LINE_COUNT;
    states_entry_view_height = (MENU_FREE_DRAW_HEIGHT - STATES_ENTRY_LINE_SPACE * (STATES_ENTRIES_LINES - 1) - STATES_PADDING_T * 2) / STATES_ENTRIES_LINES;
    states_entry_view_x_space = states_entry_view_width + STATES_ENTRY_LINE_SPACE;
    states_entry_view_y_space = states_entry_view_height + STATES_ENTRY_LINE_SPACE;
    states_entry_view_sx = MENU_FREE_DRAW_SX + STATES_PADDING_L;
    states_entry_view_sy = MENU_FREE_DRAW_SY + STATES_PADDING_T;
    states_entry_width = states_entry_view_width - STATES_ENTRY_PADDING * 2;
    states_entry_height = states_entry_view_height - STATES_ENTRY_PADDING * 2;
    states_entry_sx = states_entry_view_sx + STATES_ENTRY_PADDING;
    states_entry_sy = states_entry_view_sy + STATES_ENTRY_PADDING;
    states_entry_dx = states_entry_sx + states_entry_width;
    states_entry_dy = states_entry_sy + states_entry_height;
    states_preview_height = states_entry_height;
    states_preview_width = (states_preview_height / 3) * 4;
}

void makeSaveDirPath()
{
    char name[MAX_NAME_LENGTH];
    makeCurFileName(name);
    char base_name[MAX_NAME_LENGTH];
    makeBaseName(base_name, name, MAX_NAME_LENGTH);
    snprintf(states_dir_path, MAX_PATH_LENGTH, "%s/%s", (CORE_SAVESTATES_DIR), base_name);
}

void makeSaveStatePath(char *path, int num)
{
    if (num == -1)
        snprintf(path, MAX_PATH_LENGTH, "%s/state-auto.bin", states_dir_path);
    else
        snprintf(path, MAX_PATH_LENGTH, "%s/state-%02d.bin", states_dir_path, num);
}

int getStatesFocusPos()
{
    return states_focus_pos;
}

void setStatesFocusPos(int pos)
{
    states_focus_pos = pos;
}

static void refreshStatesEntriesPos(int *top_pos, int *focus_pos)
{
    int temp_top_pos = *top_pos;
    int temp_focus_pos = *focus_pos;

    if (temp_focus_pos > N_STATES_ENTRIES - 1)
        temp_focus_pos = N_STATES_ENTRIES - 1;
    if (temp_focus_pos < 0)
        temp_focus_pos = 0;

    int lines_center = (float)STATES_ENTRIES_LINES / 2 + 0.5f;
    int top_focus_differ = (lines_center - 1) * STATES_ENTRIES_LINE_COUNT + (temp_focus_pos % STATES_ENTRIES_LINE_COUNT);
    temp_top_pos = temp_focus_pos - top_focus_differ;

    int temp_end_pos = N_STATES_ENTRIES - 1;
    int top_end_min_differ = (STATES_ENTRIES_LINES - 1) * STATES_ENTRIES_LINE_COUNT + (temp_end_pos % STATES_ENTRIES_LINE_COUNT);
    if (temp_top_pos > temp_end_pos - top_end_min_differ)
        temp_top_pos = temp_end_pos - top_end_min_differ;
    if (temp_top_pos < 0)
        temp_top_pos = 0;

    *top_pos = temp_top_pos;
    *focus_pos = temp_focus_pos;
}

static void controlRefreshStatesEntriesPos(int type)
{
    int temp_top_pos = states_top_pos;
    int temp_focus_pos = states_focus_pos;

    if ((type == LIST_CONTROL_UP) && (temp_focus_pos >= STATES_ENTRIES_LINE_COUNT))
        temp_focus_pos -= STATES_ENTRIES_LINE_COUNT;
    else if ((type == LIST_CONTROL_DOWN) && (temp_focus_pos < N_STATES_ENTRIES - STATES_ENTRIES_LINE_COUNT))
        temp_focus_pos += STATES_ENTRIES_LINE_COUNT;
    else if (type == LIST_CONTROL_LEFT)
        temp_focus_pos--;
    else if (type == LIST_CONTROL_RIGHT)
        temp_focus_pos++;

    refreshStatesEntriesPos(&temp_top_pos, &temp_focus_pos);
    states_top_pos = temp_top_pos;
    states_focus_pos = temp_focus_pos;
}

vita2d_texture *getTextureFromSavestate(int num)
{
    char path[MAX_PATH_LENGTH];
    vita2d_texture *tex = NULL;

    makeSaveDirPath();
    makeSaveStatePath(path, num);
    SceUID fd = sceIoOpen(path, SCE_O_RDONLY, 0);
    if (fd < 0)
        return NULL;

    GameStateHeader header;
    memset(&header, 0, sizeof(GameStateHeader));
    sceIoRead(fd, &header, sizeof(GameStateHeader));
    tex = vita2d_create_empty_texture_format(header.screenshot_width, header.screenshot_height, SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
    if (tex)
    {
        sceIoLseek(fd, header.screenshot_offset, SCE_SEEK_SET);
        sceIoRead(fd, vita2d_texture_get_datap(tex), header.screenshot_size);
    }
    sceIoClose(fd);

    return tex;
}

int saveState(int num)
{
    uint32_t *screenshot_buf = NULL;
    uint32_t *preview_buf = NULL;
    void *state_buf = NULL;
    SceUID fd = -1;
    int failed = 0;
    char path[MAX_PATH_LENGTH];

    makeSaveDirPath();
    createFolder(states_dir_path);
    makeSaveStatePath(path, num);

    uint32_t base_width, base_height;
    vitaVideoMakeBaseWH(&base_width, &base_height);

    uint32_t screenshot_width, screenshot_height;
    if (graphics_config.display_rotate == 1 || graphics_config.display_rotate == 3)
    {
        screenshot_width = base_height;
        screenshot_height = base_width;
    }
    else
    {
        screenshot_width = base_width;
        screenshot_height = base_height;
    }
    
    uint64_t screenshot_size = 0;
    uint64_t screenshot_offset = sizeof(GameStateHeader);
    screenshot_buf = vitaVideoGetScreenshot(&screenshot_width, &screenshot_height, &screenshot_size);
    if (!screenshot_buf)
    {
        failed = 1;
        goto END;
    }

    uint32_t preview_width = (uint32_t)states_preview_width;
    uint32_t preview_height = (uint32_t)states_preview_height;
    uint64_t preview_size = 0;
    uint64_t preview_offset = screenshot_offset + screenshot_size;
    preview_buf = vitaVideoGetScreenshot(&preview_width, &preview_height, &preview_size);
    if (!preview_buf)
    {
        failed = 1;
        goto END;
    }

    uint64_t state_size = retro_serialize_size();
    uint64_t state_offset = preview_offset + preview_size;
    state_buf = malloc(state_size);
    if (state_size <= 0 || !state_buf)
    {
        failed = 1;
        goto END;
    }
    retro_serialize(state_buf, state_size);

    fd = sceIoOpen(path, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
    if (fd < 0)
    {
        failed = 1;
        goto END;
    }

    GameStateHeader header;
    memset(&header, 0, sizeof(GameStateHeader));
    header.version = STATES_VERSION;
    header.screenshot_offset = screenshot_offset;
    header.screenshot_width = screenshot_width;
    header.screenshot_height = screenshot_height;
    header.screenshot_size = screenshot_size;
    header.preview_offset = preview_offset;
    header.preview_width = preview_width;
    header.preview_height = preview_height;
    header.preview_size = preview_size;
    header.state_offset = state_offset;
    header.state_size = state_size;

    sceIoLseek(fd, 0, SCE_SEEK_SET);
    sceIoWrite(fd, &header, sizeof(GameStateHeader));

    sceIoLseek(fd, screenshot_offset, SCE_SEEK_SET);
    sceIoWrite(fd, screenshot_buf, screenshot_size);

    sceIoLseek(fd, preview_offset, SCE_SEEK_SET);
    sceIoWrite(fd, preview_buf, preview_size);

    sceIoLseek(fd, state_offset, SCE_SEEK_SET);
    sceIoWrite(fd, state_buf, state_size);

    if (states_entries)
    {
        if (states_entries[num].tex)
        {
            vita2d_wait_rendering_done();
            vita2d_free_texture(states_entries[num].tex);
        }
        states_entries[num].tex = vita2d_create_empty_texture_format(preview_width, preview_height, SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
        if (states_entries[num].tex)
        {
            memcpy(vita2d_texture_get_datap(states_entries[num].tex), preview_buf, preview_size);
        }

        SceIoStat stat;
        memset(&stat, 0, sizeof(SceIoStat));
        if (sceIoGetstat(path, &stat) >= 0)
        {
            states_entries[num].size = stat.st_size;
            states_entries[num].time = stat.st_mtime;
        }
        states_entries[num].exist = 1;
    }

END:
    if (screenshot_buf)
        free(screenshot_buf);
    if (preview_buf)
        free(preview_buf);
    if (state_buf)
        free(state_buf);
    if (fd >= 0)
        sceIoClose(fd);
    if (failed)
        return -1;

    return 0;
}

int loadState(int num)
{
    int ret;
    char path[MAX_PATH_LENGTH];
    if (!game_loaded)
    {
        makeCurFilePath(path);
        if (!loadGame(path))
            return -1;
    }

    makeSaveDirPath();
    makeSaveStatePath(path, num);

    int fd = sceIoOpen(path, SCE_O_RDONLY, 0);
    if (fd < 0)
        return fd;

    GameStateHeader header;
    memset(&header, 0, sizeof(GameStateHeader));

    // Read header
    sceIoLseek(fd, 0, SCE_SEEK_SET);
    sceIoRead(fd, &header, sizeof(GameStateHeader));

    if (header.version != STATES_VERSION)
    {
        APP_LOG("loadState failed: state_version is different from app_version\n");
        sceIoClose(fd);
        return -1;
    }

    uint32_t serialize_size = retro_serialize_size();
    if (header.state_size != serialize_size)
    {
        APP_LOG("loadState failed: state_size is different from serialize_size\n");
        sceIoClose(fd);
        return -1;
    }

    uint8_t *state_buf = (uint8_t *)malloc(header.state_size);
    if (!state_buf)
    {
        APP_LOG("loadState failed: can't alloc state_buf\n");
        sceIoClose(fd);
        return -1;
    }

    // Read state
    sceIoLseek(fd, header.state_offset, SCE_SEEK_SET);
    sceIoRead(fd, state_buf, header.state_size);
    sceIoClose(fd);

    ret = retro_unserialize(state_buf, header.state_size);
    if (!ret)
    {
        ret = -1;
        APP_LOG("loadState failed: retro_unserialize failed\n");
    }
    else
    {
        vitaAudioResetBuffers();
    }
    free(state_buf);

    return ret;
}

int deleteState(int num)
{
    char path[MAX_PATH_LENGTH];
    makeSaveDirPath();
    makeSaveStatePath(path, num);
    int ret = sceIoRemove(path);

    if (states_entries)
    {
        states_entries[num].exist = 0;
        if (states_entries[num].tex)
        {
            vita2d_wait_rendering_done();
            vita2d_free_texture(states_entries[num].tex);
            states_entries[num].tex = NULL;
        }
    }

    return ret;
}

int deleteAutoSavestate()
{
    int ret = 0;
    char path[MAX_PATH_LENGTH];
    makeSaveDirPath();
    makeSaveStatePath(path, -1);

    if (checkFileExist(path))
    {
        unloadPreview();
        ret = sceIoRemove(path);
    }

    return 0;
}

static int InitStatesThreadCallback(SceSize args, void *argp)
{
    SceUID dfd = sceIoDopen(states_dir_path);
    if (dfd >= 0)
    {
        int res = 0;

        do
        {
            if (stop_states_thread)
                break;

            SceIoDirent dir;
            memset(&dir, 0, sizeof(SceIoDirent));

            res = sceIoDread(dfd, &dir);
            if (res > 0)
            {
                if (strncmp(dir.d_name, "state-", 6) == 0)
                {
                    char num_str[3];
                    num_str[0] = dir.d_name[6];
                    num_str[1] = dir.d_name[7];
                    num_str[2] = '\0';

                    if (num_str[0] >= '0' && num_str[0] <= '9' &&
                        num_str[1] >= '0' && num_str[1] <= '9')
                    {
                        int num = strtol(num_str, 0, 10);
                        if (num >= N_STATES_ENTRIES)
                            continue;

                        char path[MAX_PATH_LENGTH];
                        makeSaveStatePath(path, num);

                        SceUID fd = sceIoOpen(path, SCE_O_RDONLY, 0);
                        if (fd < 0)
                            continue;

                        // Read header
                        GameStateHeader header;
                        memset(&header, 0, sizeof(GameStateHeader));
                        sceIoRead(fd, &header, sizeof(GameStateHeader));

                        if (header.version != STATES_VERSION)
                        {
                            sceIoClose(fd);
                            continue;
                        }

                        // Read framebuffer
                        states_entries[num].tex = vita2d_create_empty_texture_format(header.preview_width, header.preview_height, SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
                        if (states_entries[num].tex)
                        {
                            sceIoLseek(fd, header.preview_offset, SCE_SEEK_SET);
                            sceIoRead(fd, vita2d_texture_get_datap(states_entries[num].tex), header.preview_size);
                        }

                        // Set file stat
                        SceIoStat stat;
                        memset(&stat, 0, sizeof(SceIoStat));
                        if (sceIoGetstat(path, &stat) >= 0)
                        {
                            states_entries[num].size = stat.st_size;
                            states_entries[num].time = stat.st_mtime;
                        }

                        // Set exist
                        states_entries[num].exist = 1;

                        sceIoClose(fd);
                    }
                }
            }
        } while (res > 0);

        sceIoDclose(dfd);
    }

    sceKernelExitDeleteThread(0);
    return 0;
}

void initStatesThread()
{
    stop_states_thread = 0;
    init_states_thread = sceKernelCreateThread("init_states_thread", InitStatesThreadCallback, 0x10000100, 0x10000, 0, 0, NULL);
    if (init_states_thread >= 0)
        sceKernelStartThread(init_states_thread, 0, NULL);
}

void finishStatesThread()
{
    stop_states_thread = 1;
    if (init_states_thread < 0)
        return;
    
    sceKernelWaitThreadEnd(init_states_thread, NULL, NULL);
    sceKernelDeleteThread(init_states_thread);
    init_states_thread = -1;
}

int initStates()
{
    options_open = 0;

    states_entries = malloc(N_STATES_ENTRIES * sizeof(GameStateEntry));
    if (!states_entries)
        return -1;

    memset(states_entries, 0, N_STATES_ENTRIES * sizeof(GameStateEntry));
    makeSaveDirPath();

    // Clear
    int i;
    for (i = 0; i < N_STATES_ENTRIES; i++)
    {
        states_entries[i].exist = 0;
        states_entries[i].tex = NULL;
    }

    controlRefreshStatesEntriesPos(LIST_CONTROL_NONE);
    initStatesThread();
    
    return 0;
}

int finishStates()
{
    finishStatesThread();

    if (states_entries)
    {
        vita2d_wait_rendering_done();
        int i;
        for (i = 0; i < N_STATES_ENTRIES; i++)
        {
            if (states_entries[i].tex)
            {
                vita2d_free_texture(states_entries[i].tex);
                states_entries[i].tex = NULL;
            }
        }
        free(states_entries);
        states_entries = NULL;
    }

    return 0;
}

void drawStates()
{
    float entry_view_sx = states_entry_view_sx;
    float entry_view_sy = states_entry_view_sy;
    float entry_sx = states_entry_sx;
    float entry_sy = states_entry_sy;
    float entry_dx = states_entry_dx;
    float entry_dy = states_entry_dy;
    float line_height = UiGetLineHeight();

    int i;
    int drawed_counts = 0;
    for (i = states_top_pos; i < N_STATES_ENTRIES; i++)
    {
        if (drawed_counts > STATES_ENTRIES_LINES * STATES_ENTRIES_LINE_COUNT)
            break;

        uint32_t color = (i == states_focus_pos) ? STATES_ENTRY_FOCUS_BG_COLOR : STATES_ENTRY_BG_COLOR;
        vita2d_draw_rectangle(entry_view_sx, entry_view_sy, states_entry_view_width, states_entry_view_height, color);

        float preview_sx = entry_sx;
        float preview_sy = entry_sy;
        float info_sx = preview_sx + states_preview_width + STATES_INFO_MARGIN_L;
        float info_sy = preview_sy + states_preview_height - line_height;
        if (states_entries[i].exist)
        {
            // Preview
            if (states_entries[i].tex)
            {
                float tex_width = (float)vita2d_texture_get_width(states_entries[i].tex);
                float tex_height = (float)vita2d_texture_get_height(states_entries[i].tex);
                float scale_x = states_preview_width / tex_width;
                float scale_y = states_preview_height / tex_height;
                vita2d_draw_texture_scale(states_entries[i].tex, preview_sx, preview_sy, scale_x, scale_y);
            }

            // Date & time
            char date_string[24];
            getDateString(date_string, date_format, &states_entries[i].time);
            char time_string[16];
            getTimeString(time_string, time_format, &states_entries[i].time);
            UiDrawTextf(info_sx, info_sy, LITEGRAY, "%s %s", date_string, time_string);
            info_sy -= (line_height + STATES_INFO_LINE_SPACE);
            UiDrawTextf(info_sx, info_sy, LITEGRAY, (STR_EXIST_SAVESTATE " %d"), i);
        }
        else
        {
            vita2d_draw_rectangle(preview_sx, preview_sy, states_preview_width, states_preview_height, STATES_PREVIEW_BG_COLOR);
            UiDrawTextf(info_sx, info_sy, LITEGRAY, (STR_NEW_SAVESTATE " %d"), i);
        }

        if (options_open && i == states_focus_pos)
        {
            int j;
            float option_sx = entry_dx;
            float option_sy = entry_sy;
            for (j = 0; j < N_OPTION_ENTRIES; j++)
            {
                if (option_entries[j].enable)
                {
                    uint32_t color = (j == options_focus_pos) ? GREEN : WHITE;
                    UiDrawTextf(option_sx - UiGetTextWidth(option_entries[j].name), option_sy, color, option_entries[j].name);
                    option_sy += (line_height + STATES_OPATION_LINE_SPACE);
                }
            }
        }

        if ((i % STATES_ENTRIES_LINE_COUNT) < (STATES_ENTRIES_LINE_COUNT - 1))
        {
            entry_view_sx += states_entry_view_x_space;
            entry_sx += states_entry_view_x_space;
            entry_dx += states_entry_view_x_space;
        }
        else
        {
            entry_view_sx = states_entry_view_sx;
            entry_sx = states_entry_sx;
            entry_dx = states_entry_dx;
            entry_view_sy += states_entry_view_y_space;
            entry_sy += states_entry_view_y_space;
            entry_dy += states_entry_view_y_space;
        }
        drawed_counts++;
    }
}

void ctrlStates()
{
    if (options_open)
    {
        if (released_pad[PAD_CANCEL])
        {
            options_open = 0;
        }

        if (released_pad[PAD_ENTER])
        {
            switch (options_focus_pos)
            {
            case 0:
            {
                loadState(states_focus_pos);
                exitMenu();
                break;
            }

            case 1:
            {
                saveState(states_focus_pos);
                options_open = 0;
                break;
            }

            case 2:
            {
                deleteState(states_focus_pos);
                options_open = 0;
                break;
            }

            case 3:
            {
                options_open = 0;
                break;
            }
            }
        }

        if (hold_pad[PAD_UP] || hold_pad[PAD_LEFT_ANALOG_UP])
        {
            int i = options_focus_pos - 1;
            while (i >= 0)
            {
                if (option_entries[i].enable)
                {
                    options_focus_pos = i;
                    break;
                }
                i--;
            }
        }
        else if (hold_pad[PAD_DOWN] || hold_pad[PAD_LEFT_ANALOG_DOWN])
        {
            int i = options_focus_pos + 1;
            while (i <= (N_OPTION_ENTRIES - 1))
            {
                if (option_entries[i].enable)
                {
                    options_focus_pos = i;
                    break;
                }
                i++;
            }
        }
    }
    else
    {
        if (hold_pad[PAD_UP] || hold_pad[PAD_LEFT_ANALOG_UP])
        {
            controlRefreshStatesEntriesPos(LIST_CONTROL_UP);
        }
        else if (hold_pad[PAD_DOWN] || hold_pad[PAD_LEFT_ANALOG_DOWN])
        {
            controlRefreshStatesEntriesPos(LIST_CONTROL_DOWN);
        }
        else if (hold_pad[PAD_LEFT] || hold_pad[PAD_LEFT_ANALOG_LEFT])
        {
            controlRefreshStatesEntriesPos(LIST_CONTROL_LEFT);
        }
        else if (hold_pad[PAD_RIGHT] || hold_pad[PAD_LEFT_ANALOG_RIGHT])
        {
            controlRefreshStatesEntriesPos(LIST_CONTROL_RIGHT);
        }

        if (released_pad[PAD_ENTER])
        {
            options_open = 1;
            options_focus_pos = 0;

            if (states_entries[states_focus_pos].exist)
            {
                option_entries[0].enable = 1;
                option_entries[2].enable = 1;
            }
            else
            {
                option_entries[0].enable = 0;
                option_entries[2].enable = 0;
            }
            if (game_loaded)
                option_entries[1].enable = 1;
            else
                option_entries[1].enable = 0;

            for (int i = 0; i < N_OPTION_ENTRIES; i++)
            {
                if (option_entries[i].enable)
                {
                    options_focus_pos = i;
                    break;
                }
            }
        }

        if (released_pad[PAD_CANCEL])
        {
            exitMenu();
        }
    }
}